package algo3.juegoCarmenSanDiego.modelo;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;



import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;


public class Caso {
	
	private String nombreDeArchivo;
	private List<Ciudad> ciudadesDelLadron = new ArrayList<Ciudad>();
	private List<Ciudad> ciudadesSinPista = new ArrayList<Ciudad>();
	private String nombreDeLadron;
	private String objetoRobado;
	private Boolean ultimaCiudadDelLadron;
	private TipoEdificioEnum edificioDeEscondite;
	private int iteradorDeRecorridoLadron;
	private int iteradorSinPista;
	
	

	public Caso(String unNombreDeArchivo) throws SAXException, IOException, ParserConfigurationException{
		this.nombreDeArchivo=unNombreDeArchivo;
		this.hidratarLasCiudadesYsusPistas();
		this.iteradorDeRecorridoLadron = 0;
		this.iteradorSinPista=0;
		this.ultimaCiudadDelLadron=false;
		generarEdificioDondeSeOcultaElLadron();
	}
	private void generarEdificioDondeSeOcultaElLadron(){
		List<Edificio> listaDeEdificios =  this.ciudadesDelLadron.get(this.ciudadesDelLadron.size()-1).getEdificiosEnUnaLista();
		Random random = new Random();
		int numeroRandom = random.nextInt(3) + 1;
		switch (numeroRandom) {
	      case 1:
	           this.edificioDeEscondite=listaDeEdificios.get(0).getTipoDeEdificio();
	           break;
	      case 2:
	    	  this.edificioDeEscondite=listaDeEdificios.get(1).getTipoDeEdificio();
	           break;
	      case 3:
	    	  this.edificioDeEscondite=listaDeEdificios.get(2).getTipoDeEdificio();
	           break;
		}
	}
	public String obtenerLadron(){
		return this.nombreDeLadron;
	}
	public String getObjetoRobado(){
		return this.objetoRobado;
	}
	public int getIterador(){
		return this.iteradorDeRecorridoLadron;
	}
	public int getIteradorSinPista(){
		return this.iteradorSinPista;
	}
	public void generarLadron(String unNombre){
		this.nombreDeLadron=unNombre;
	}
	public void agregarCiudadSinPista(Ciudad unaCiudad){
		this.ciudadesSinPista.add(unaCiudad);
	}
	public void agregarCiudadDelLadron(Ciudad unaCiudad){
		ciudadesDelLadron.add(unaCiudad);
	}
	public Ciudad obtenerCiudadSinPista(int unNumero){
		return this.ciudadesSinPista.get(unNumero);
	}
	public Ciudad getCiudadSinPistaYPosicionarEnSiguiente(){
		if (this.ciudadesSinPista.size()==this.iteradorSinPista){
			this.iteradorSinPista=0;
		}
		Ciudad unaCiudad = obtenerCiudadSinPista(iteradorSinPista);
		iteradorSinPista++;
		return unaCiudad;
	}
	public Ciudad obtenerCiudadDelLadron(int unNumero){
		return this.ciudadesDelLadron.get(unNumero);
	}
	public List<Ciudad> getListaDeCiudadesSinPista(){
		return ciudadesSinPista;
	}
	public List<Ciudad> getListaDeCiudadesDelLadron(){
		return ciudadesDelLadron;
	}
	public String getNombreDeLadron(){
		return this.nombreDeLadron;
	}
	
	public String obtenerLadronPorSusDescripciones(Ladron unaDescripcion){
		return nombreDeLadron;
	}
		
	private void hidratarLasCiudadesYsusPistas() throws SAXException, IOException, ParserConfigurationException{
		
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document doc = db.newDocument();
		
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		
		File archivo = new File(nombreDeArchivo);
		
		doc = dBuilder.parse(archivo);
		
			Element elementoDeDescripcion = (Element) doc.getElementsByTagName("descripcion").item(0);
			this.nombreDeLadron= elementoDeDescripcion.getAttribute("nombreDelLadron");
			this.objetoRobado= elementoDeDescripcion.getAttribute("objetoRobado");
			
			Element elementoCiudadesDelLadron = (Element) elementoDeDescripcion.getElementsByTagName("ciudadesLadron").item(0);
			
			for(int i=0; i< elementoCiudadesDelLadron.getChildNodes().getLength(); i++) {
				Ciudad ciudad = Ciudad.cargarAMemoria((Element)elementoCiudadesDelLadron.getChildNodes().item(i));
				ciudadesDelLadron.add(ciudad);
			}
			Element elementoCiudadesSinPista = (Element) elementoDeDescripcion.getElementsByTagName("ciudadesSinPista").item(0);
			
			for(int i=0; i< elementoCiudadesSinPista.getChildNodes().getLength(); i++) {
				Ciudad ciudad = Ciudad.cargarAMemoria((Element)elementoCiudadesSinPista.getChildNodes().item(i));
				ciudadesSinPista.add(ciudad);
			}
		}
	public Ciudad getCiudadDeLadronYPosicionarEnSiguiente(){
		if (this.ciudadesDelLadron.size()-1==this.iteradorDeRecorridoLadron){
			this.ultimaCiudadDelLadron=true;
		}
		Ciudad unaCiudad = ciudadesDelLadron.get(iteradorDeRecorridoLadron);
		iteradorDeRecorridoLadron++;
		return unaCiudad;
	}
	
	 
	
	private List<Ciudad> getDosCiudadesQueNoDanPista(){
		List<Ciudad> ciudadesSinPistaAlAzar = new ArrayList<Ciudad>();
		//aca hay que cambiar this.ciudades por this.ciudadesQuenotienepistaOAlgoAsi 
		int enteroAlAzar1 = (int) (Math.random() * ( this.ciudadesSinPista.size() ));
		int enteroAlAzar2 = (int) (Math.random() * ( this.ciudadesSinPista.size() ));
		while (enteroAlAzar1 == enteroAlAzar2){
			enteroAlAzar1 = (int) (Math.random() * ( this.ciudadesSinPista.size() ));
		}
		ciudadesSinPistaAlAzar.add(this.ciudadesSinPista.get(enteroAlAzar1));
		ciudadesSinPistaAlAzar.add(this.ciudadesSinPista.get(enteroAlAzar2));
		return ciudadesSinPistaAlAzar;
	}
	private List<Ciudad> getTresCiudadesQueNoDanPista(){
		List<Ciudad> ciudadesSinPistaAlAzar = new ArrayList<Ciudad>();
		//aca hay que cambiar this.ciudades por this.ciudadesQuenotienepistaOAlgoAsi 
		int enteroAlAzar1 = (int) (Math.random() * ( this.ciudadesSinPista.size() ));
		int enteroAlAzar2 = (int) (Math.random() * ( this.ciudadesSinPista.size() ));
		int enteroAlAzar3 = (int) (Math.random() * ( this.ciudadesSinPista.size() ));
		while (enteroAlAzar2 == enteroAlAzar3){
			enteroAlAzar3 = (int) (Math.random() * ( this.ciudadesSinPista.size() ));
		}
		Boolean diferentes=false;
		while(!diferentes){
			enteroAlAzar1 = (int) (Math.random() * ( this.ciudadesSinPista.size() ));
			if (enteroAlAzar2 !=enteroAlAzar1 && enteroAlAzar3 !=enteroAlAzar1){
					diferentes=true;
			}
		}
		ciudadesSinPistaAlAzar.add(this.ciudadesSinPista.get(enteroAlAzar1));
		ciudadesSinPistaAlAzar.add(this.ciudadesSinPista.get(enteroAlAzar2));
		ciudadesSinPistaAlAzar.add(this.ciudadesSinPista.get(enteroAlAzar3));
		return ciudadesSinPistaAlAzar;
	}
	
	public List<Ciudad> getCiudadesParaMostrarAlPolicia(){
		List<Ciudad> ciudadesParaMostrarPolicia = new ArrayList<Ciudad>();
		List<Ciudad> ciudadesAlAzar;
		if (!this.ultimaCiudadDelLadron){
			ciudadesAlAzar = this.getDosCiudadesQueNoDanPista();
			for (int i =0 ; i< ciudadesAlAzar.size(); i++)
				ciudadesParaMostrarPolicia.add(ciudadesAlAzar.get(i));
			ciudadesParaMostrarPolicia.add(this.getCiudadDeLadronYPosicionarEnSiguiente());
			return ciudadesParaMostrarPolicia;
		}
		else{
			ciudadesAlAzar = this.getTresCiudadesQueNoDanPista();
			for (int i =0 ; i< ciudadesAlAzar.size(); i++)
				ciudadesParaMostrarPolicia.add(ciudadesAlAzar.get(i));
			return ciudadesParaMostrarPolicia;
		}
	}
	public String getNombreCiudadInicio() {
		return this.ciudadesDelLadron.get(0).getNombreDeCiudad();
	}
	public Boolean esUltimaCiudad(String ciudadDelPolicia){
		return (this.ciudadesDelLadron.get(this.ciudadesDelLadron.size()-1).getNombreDeCiudad().compareTo(ciudadDelPolicia)== 0);
	}
	public TipoEdificioEnum edificioDeEsconditeDelLadron(){
		return this.edificioDeEscondite;
	}
	public Ciudad getCiudadDeInicio(){
		return ciudadesDelLadron.get(0);
	}
	public String getNombreCiudadDeEscondite() {
		return this.ciudadesDelLadron.get(this.ciudadesDelLadron.size()-1).getNombreDeCiudad();
		
	}
	public TipoEdificioEnum getEdificioDeEscondite(){
		return this.edificioDeEscondite;
	}
}